package com.baiyue.utils;

import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;

import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;
import java.util.UUID;

/**
 * 安全性，校验性操作
 *
 * @author tangfan 2018/8/31 11:13
 */
public class SecurityUtil {
    private static final int SECRET_SIZE = 32;

    private static final String SEED = "VK6QB6AYFAZTYATRDLL7K4ZX6EFVQ56XX4U5GCZFIIMWTISWSPZXWLCEQTX67HYMGRBKKZ4QI2VQOTQZBXWFTTV522E3DK4OCDQWTKY=";

    private static final String RANDOM_NUMBER_ALGORITHM = "SHA1PRNG";

    /**
     * 生成随机密钥
     *
     * @param length 长度
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static String generateSecretKey(int length) throws NoSuchAlgorithmException {
        SecureRandom secureRandom;
        secureRandom = SecureRandom.getInstance(RANDOM_NUMBER_ALGORITHM);
        secureRandom.setSeed(Base64.getDecoder().decode(SEED));
        byte[] buffer = secureRandom.generateSeed(length);
        Base32 codec = new Base32();
        byte[] bEncodedKey = codec.encode(buffer);
        return new String(bEncodedKey);
    }

    /**
     * 使用默认长度32位生成密钥
     *
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static String generateSecretKey() throws NoSuchAlgorithmException {
        return generateSecretKey(SECRET_SIZE);
    }

    /**
     * 执行签名
     *
     * @param target 需要签名的对象
     * @param key    密钥
     * @return 签名
     */
    public static String sign(Object target, String key) {
        if (target == null) {
            throw new IllegalArgumentException("签名对象不能为空！");
        }
        String url = sort(target);
        if (StringUtils.isNotEmpty(key)) {
            key = "junbo-common-" + key;
            url += "&key=" + key;
        }
        return DigestUtils.md5Hex(url);
    }

    /**
     * 普通签名
     *
     * @param target 需要签名的对象
     * @return 签名
     */
    public static String sign(Object target) {
        return sign(target, null);
    }

    /**
     * 签名检验
     *
     * @param target
     * @param sign
     * @return
     */
    public static boolean checkSign(Object target, String sign) {
        return StringUtils.equalsIgnoreCase(sign(target), sign);
    }

    /**
     * 签名检验
     *
     * @param target
     * @param key
     * @param sign
     * @return
     */
    public static boolean checkSign(Object target, String key, String sign) {
        return StringUtils.equalsIgnoreCase(sign(target, key), sign);
    }

    /**
     * 将对象以ASCII方式升序排列
     *
     * @param target 排序对象
     * @return 排序后的键值对字符串
     */
    private static String sort(Object target) {
        String[] array = JsonMapperUtil.toUri(target).split("&");
        Arrays.sort(array);
        return StringUtils.join(array, "&");
    }

    /**
     * 随机生成纯数字16位
     * @return
     */
    public static String generate(){
        UUID uuid = UUID.randomUUID();
        long mostSignificantBits = uuid.getMostSignificantBits();
        long leastSignificantBits = uuid.getLeastSignificantBits();
        String concatenatedBits = Long.toString(mostSignificantBits, 16)
                + Long.toString(leastSignificantBits, 16);
        return concatenatedBits.replaceAll("[^0-9]", "").substring(0, 16);
    }
}